package cn.yesway.springioc.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
/**
 * Java允许通过程序化的方式间接的对Class进行操作，Class文件由类加载器装载后，在jvm中形成一份Class结构的元信息对象。
 * 通过元信息对象可以获取Class的结构信息：构造器、属性和方法等
 * Java允许用户借用Class相关的元信息对象间接调用Class对象的功能。
 * @comment:
 * @author chencq
 * @Email:hero901027@163.com
 */
public class ReflectTest {
	public static Car  initByDefaultConst() throws Throwable
	{
		//①通过类装载器获取Car类对象
		/**
		 * ClassLoader是一个重要的Java运行时系统组件，它负责在运行时查找和装入Class字节码文件。
		 * jvm在运行时会产生三个ClassLoader：根装载器，ExtClassLoader(拓展类加载器)、AppClassLoader(系统类装载器)
		 * 根装载器不是ClassLoader的子类，它使用C++编写，因此我们在Java中看不到它，核心
		 * ExtClassLoader和AppClassLoader都是ClassLoader的子类
		 * ExtClassLoader负责装载JRE扩展目录ext中的JAR类包
		 * AppClassLoader负责装载Classpath路径下的类包
		 * 根装载器是ExtClassLoader的父装载器，ExtClassLoader是AppClassLoader的父装载器
		 */
		ClassLoader loader = Thread.currentThread().getContextClassLoader(); 
		 System.out.println("current loader:"+loader);
		 System.out.println("parent loader:"+loader.getParent()); 
		 System.out.println("grandparent loader:"+loader.getParent(). getParent());  
		 
		Class clazz = loader.loadClass("cn.yesway.springioc.reflect.Car"); 
		
          //②获取类的默认构造器对象并通过它实例化Car
		Constructor cons = clazz.getDeclaredConstructor((Class[])null); 
		Car car = (Car)cons.newInstance();//等同于new Car()
         
          //③通过反射方法设置属性
		Method setBrand = clazz.getMethod("setBrand",String.class);	       
		setBrand.invoke(car,"红旗CA72");		
		Method setColor = clazz.getMethod("setColor",String.class);
		setColor.invoke(car,"黑色");		
		Method setMaxSpeed = clazz.getMethod("setMaxSpeed",int.class);
		setMaxSpeed.invoke(car,200);		
		return car;
	}

	public static void main(String[] args) throws Throwable {
		Car car = initByDefaultConst();
		car.introduce();
	}
}